import { APlugin } from '../types/common.interface';
import { TableDatas } from '../cors/table-datas';
import { Injectable, PluginInjectable, Inject, InjectFactory, TFactory } from '../decorators/inject';
import { Select } from '../cors/select';
import { ExecuteRecord } from '../cors/execute-record';
import { RenderTrigger } from '../cors/render-trigger';
import { CellTypeManage } from '../cors/cell-type-manage';
import { TableEvent } from '../cors/table-event';
import { NExcel } from '../types';
import { Cache } from '../cors/cache';
import { Config } from '../cors/config';
import { Hook } from '../cors/hook';
import { ICellGroup, CellTypes, ICellEditor, ICellRender, ICellEditorDestroy } from '../cell-types';
import './edit.less';
@Injectable()
@PluginInjectable('EditPlugin')
export class EditPlugin extends APlugin {
    protected container!: HTMLElement;
    protected editContainer!: HTMLElement|null;
    protected editCellLocation!: TRange;
    protected currentEditor!: (ICellEditor & Partial<ICellEditorDestroy>) | null;
    protected currentEditorInfo: {row: number, col: number}|null = null;
    protected eventProxy!: {preventDefault: boolean, target:HTMLElement};
    constructor(
        protected tableEvent: TableEvent,
        @Inject(NExcel.TableContainerEleToken) protected tableContainer: HTMLElement,
        protected conf: Config,
        protected cache: Cache,
        protected hook: Hook,
        protected cellTypeMgr: CellTypeManage,
        protected tableDatas: TableDatas,
        protected renderTrigger: RenderTrigger,
        @InjectFactory() public factory: TFactory
    ) {
        super();
        this.eventProxy = new Proxy<{preventDefault: boolean, target:HTMLElement}>({preventDefault: false, target: this.container}, {
            get: (target, p) => {
                if(p !== 'preventDefault') {
                    if(__ENV__ === 'development') {
                        throw new Error(`cant find property ${String(p)}`)
                    } else {
                        console.error(`cant find property ${String(p)}`)
                    }
                }
                return target.preventDefault;
            },
            set: (target, p: 'preventDefault', val: boolean) => {
                if(p !== 'preventDefault') {
                    if(__ENV__ === 'development') {
                        throw new Error(`cant find property ${String(p)}`)
                    } else {
                        console.error(`cant find property ${String(p)}`)
                    }
                } else {
                    if(val) {
                        this.container && this.container.setAttribute('style', 'pointer-events:all;');
                        this.editContainer && this.editContainer.classList.remove('z-excel-editor-container-overhidden');
                    } else {
                        this.container && this.container.setAttribute('style', 'pointer-events:none;');
                        this.editContainer && this.editContainer.classList.add('z-excel-editor-container-overhidden');
                    }
                }
                target[p] = val;
                return true;
            }
        });
    }
    public init() {
        this.container = this.tableContainer.querySelector('.z-table-edit-container');
        this.tableEvent.dbclick$.subscribe(evt => {
            console.log('dbclick',evt)
            if(this.currentEditorInfo !== null) {
                if(evt.row !== this.currentEditorInfo.row || evt.col !== this.currentEditorInfo.col) {
                    this.autoFinishEditor();
                }
            }
            this.currentEditorInfo = {row: evt.row, col: evt.col};
            this.createCellEditContainer(evt.row, evt.col, evt.rowspan, evt.colspan);
            let cell = this.tableDatas.getRow(evt.row).getCell(evt.col);
            let cellType = this.tableDatas.getCellType(evt.row, evt.col);
            try {
                let Editor = this.cellTypeMgr.getEditor(cellType);
                this.currentEditor = this.factory(Editor);
                this.eventProxy.preventDefault = false;
                this.currentEditor.initEditor(cell, this.editContainer, this.destroyEditor.bind(this), this.eventProxy);
            } catch (error) {
                console.error(error)
            }

        });
        this.hook.afterRender.add(() =>{
            this.updatePosition();
        });
        this.tableEvent.click$.subscribe(evt => {
            if(this.currentEditorInfo === null) return;
            if(evt.row !== this.currentEditorInfo.row || evt.col !== this.currentEditorInfo.col) {
                this.autoFinishEditor();
            }
        });
    }
    protected destroyEditor() {
        if(this.currentEditor.destroy) {
            try {
                this.currentEditor.destroy();
            } catch (error) {
                console.error(error);
            }
        }
        this.currentEditor = null;
        this.editContainer.remove();
        this.renderTrigger.triggerRenderAll();
    }
    protected autoFinishEditor() {
        // if(this.currentEditor) {
        //     try {
        //         this.currentEditor.finish();
        //         if(this.currentEditor.finish.length === 0) {
                    
        //         }
        //     } catch (error) {
        //         console.error(error);
        //     }
        // }
        if(this.currentEditor) {
            this.currentEditor.finish()
            this.destroyEditor();
            this.renderTrigger.triggerRenderAll();
        }
    }
    public destroy(): void {
        
    }
    protected createCellEditContainer(row: number, col: number, rowspan: number, colspan: number) {
        // let position = this.cache.getClipRect({row, col, rowspan, colspan});
        this.editContainer =  document.createElement('div');
        this.editContainer.setAttribute('class', 'z-excel-editor-container');
        // this.editContainer.innerHTML = `<div class=“z-excel-editor-content”></div>`;
        this.container.append(this.editContainer);
        this.editCellLocation = {
            row,col,rowspan,colspan
        };
        this.updatePosition();
    }
    protected updatePosition() {
        if(!this.editContainer) return;
        let positionRect = this.cache.getClipRect(this.editCellLocation);
        this.editContainer.setAttribute('style', `
            top: ${positionRect.y/this.conf.pixelRatio}px;
            left: ${positionRect.x/this.conf.pixelRatio}px;
            width: ${(positionRect.w)/this.conf.pixelRatio}px;
            height: ${(positionRect.h)/this.conf.pixelRatio}px;
            background-color: red1;
        `)
    }
}
